﻿using System;

namespace UtilZ.Dotnet.Ex.Base
{
    /// <summary>
    /// 时间扩展类
    /// 所用时间戳的基准时间为1970-1-1 0:0:0.000,时间戳单位:毫秒
    /// </summary>
    public class TimeEx
    {
        private const DateTimeKind _DEFAULT = DateTimeKind.Local;
        private static ITimestampFactory _timestampFactory;
        /// <summary>
        /// 获取或设置时间戳工厂对象
        /// </summary>
        public static ITimestampFactory TimestampFactory
        {
            get { return _timestampFactory; }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException(nameof(value));
                }

                _timestampFactory = value;
            }
        }


        static TimeEx()
        {
            //DateTime refTime;
            //if (EnvironmentEx.OS == OSPlatformID.Win)
            //{
            //    refTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Local);
            //}
            //else
            //{
            //    //long unix_timestamp = (t.Ticks - dt1970.ToLocalTime().Ticks) / (10000 * 1000); //加上ToLocalTime方法，将格林尼治时间1970/1/1转为北京时间
            //    TimeSpan ts = DateTime.Now - DateTime.UtcNow;
            //    refTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Local).Subtract(ts);
            //}

            //_timestampFactory = new TimestampFactory(new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Local));
            _timestampFactory = new TicksTimestampFactory(new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Local));


            //_localTimestampFactory = new TimestampFactory(DateTimeKind.Local);
            //_utcTimestampFactory = new TimestampFactory(DateTimeKind.Utc);
            //_unspecifiedTimestampFactory = new TimestampFactory(DateTimeKind.Unspecified);
        }


        #region common

        /// <summary>
        /// 获取当前时间
        /// </summary>
        /// <param name="kind">时间类型</param>
        public static DateTime GetNow(DateTimeKind kind)
        {
            DateTime dateTime;
            switch (kind)
            {
                case DateTimeKind.Local:
                    dateTime = DateTime.Now;
                    break;
                case DateTimeKind.Utc:
                    dateTime = DateTime.UtcNow;
                    break;
                case DateTimeKind.Unspecified:
                    dateTime = TimeEx.ConvertDateTimeKind(DateTime.Now, DateTimeKind.Unspecified);
                    break;
                default:
                    throw new NotImplementedException(kind.ToString());
            }

            return dateTime;
        }

        /// <summary>
        /// 获取当前时间
        /// </summary>
        public static DateTime GetNow()
        {
            return GetNow(_timestampFactory.RefTime.Kind);
        }

        /// <summary>
        /// 转换DateTimeOffset为DateTime
        /// </summary>
        /// <param name="dateTime">DateTimeOffset</param>
        /// <param name="kind">目标时间类型</param>
        /// <returns>DateTime</returns>
        public static DateTime ConvertDateTimeOffsetToDateTime(DateTimeOffset dateTime, DateTimeKind kind)
        {
            DateTime time;
            switch (kind)
            {
                case DateTimeKind.Local:
                    time = dateTime.LocalDateTime;
                    break;
                case DateTimeKind.Utc:
                    time = dateTime.UtcDateTime;
                    break;
                case DateTimeKind.Unspecified:
                    time = dateTime.DateTime;
                    break;
                default:
                    throw new NotSupportedException(kind.ToString());
            }

            return time;
        }

        /// <summary>
        /// 将已知时间转换为另一种表示的时间
        /// </summary>
        /// <param name="time">已知时间</param>
        /// <param name="targetKind">目标时间类型</param>
        /// <returns>目标时间</returns>
        public static DateTime ConvertDateTimeKind(DateTime time, DateTimeKind targetKind)
        {
            if (time.Kind == targetKind)
            {
                return time;
            }

            switch (targetKind)
            {
                case DateTimeKind.Local:
                    time = time.ToLocalTime();
                    break;
                case DateTimeKind.Utc:
                    time = time.ToUniversalTime();
                    break;
                case DateTimeKind.Unspecified:
                    time = new DateTime(time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second, time.Millisecond, DateTimeKind.Unspecified);
                    break;
                default:
                    throw new NotSupportedException(targetKind.ToString());
            }

            return time;
        }

        /// <summary>
        /// 获取永久时间片
        /// </summary>
        /// <returns>永久时间片</returns>
        public static TimeSpan GetForeverTimeSpan()
        {
            //将1000年当作为永久时间
            return new TimeSpan(365 * 1000, 0, 0, 0, 0);
        }

        #endregion



        #region 基准时间1970-1-1 0:0:0.000时间戳
        /// <summary>
        /// 获取指定日期时间的时间戳
        /// </summary>
        /// <param name="dateTime">计算时间戳时间</param>
        /// <returns>当前时间的时间戳</returns>
        public static double GetTimestampD(DateTime dateTime)
        {
            return _timestampFactory.GetTimestamp(dateTime);
        }

        /// <summary>
        /// 获取指定日期时间的时间戳
        /// </summary>
        /// <param name="dateTime">计算时间戳时间</param>
        /// <returns>当前时间的时间戳</returns>
        public static long GetTimestamp(DateTime dateTime)
        {
            return Convert.ToInt64(GetTimestampD(dateTime));
        }




        /// <summary>
        /// 获取指定日期时间的时间戳
        /// </summary>
        /// <param name="dateTime">计算时间戳时间</param>
        /// <returns>当前时间的时间戳</returns>
        public static double GetTimestampD(DateTimeOffset dateTime)
        {
            DateTime time = ConvertDateTimeOffsetToDateTime(dateTime, _timestampFactory.RefTime.Kind);
            return _timestampFactory.GetTimestamp(time);
        }

        /// <summary>
        /// 获取指定日期时间的时间戳
        /// </summary>
        /// <param name="dateTime">计算时间戳时间</param>
        /// <returns>当前时间的时间戳</returns>
        public static long GetTimestamp(DateTimeOffset dateTime)
        {
            return Convert.ToInt64(GetTimestampD(dateTime));
        }

        /// <summary>
        /// 获取当前时间的时间戳
        /// </summary>
        /// <returns>当前时间的时间戳</returns>
        public static long GetTimestamp()
        {
            return _timestampFactory.GetTimestamp();
        }




        /// <summary>
        /// 时间戳转换为DateTime
        /// </summary>
        /// <param name="timestamp">时间戳</param>
        /// <param name="dateTimeKind">时间类型,默认类型为本地时间</param>
        /// <returns>时间</returns>
        public static DateTime TimestampToDateTime(long timestamp, DateTimeKind dateTimeKind = _DEFAULT)
        {
            DateTime dateTime = _timestampFactory.TimestampToDateTime(timestamp);

            if (dateTime.Kind != dateTimeKind)
            {
                dateTime = TimeEx.ConvertDateTimeKind(dateTime, dateTimeKind);
            }

            return dateTime;
        }

        /// <summary>
        /// 时间戳转换为DateTime
        /// </summary>
        /// <param name="timestamp">时间戳</param>
        /// <param name="dateTimeKind">时间类型,默认类型为本地时间</param>
        /// <returns>时间</returns>
        public static DateTime TimestampToDateTime(double timestamp, DateTimeKind dateTimeKind = _DEFAULT)
        {
            DateTime dateTime = _timestampFactory.TimestampToDateTime(timestamp);

            if (dateTime.Kind != dateTimeKind)
            {
                dateTime = TimeEx.ConvertDateTimeKind(dateTime, dateTimeKind);
            }

            return dateTime;
        }

        /// <summary>
        /// 时间戳转换为DateTimeOffset
        /// </summary>
        /// <param name="timestamp">时间戳</param>
        /// <param name="dateTimeKind">时间类型,默认类型为本地时间</param>
        /// <returns>时间</returns>
        public static DateTimeOffset TimestampToDateTimeOffset(long timestamp, DateTimeKind dateTimeKind = _DEFAULT)
        {
            DateTime dateTime = TimestampToDateTime(timestamp, dateTimeKind);
            return new DateTimeOffset(dateTime);
        }

        #endregion


        //备份一
        /**********************************************************************************************************************************************

        #region TicksTimestamp

        /// <summary>
        /// 获取指定时间的Ticks时间戳
        /// </summary>
        /// <param name="dateTime">时间</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>Ticks时间戳</returns>
        public static double GetTicksTimestampD(DateTime dateTime, TimestampUnit timestampUnit = TimestampUnit.Millisecond, uint precision = 1)
        {
            return _timestampFactory.GetTicksTimestampD(dateTime, timestampUnit, precision);
        }

        /// <summary>
        /// 获取指定时间的Ticks时间戳
        /// </summary>
        /// <param name="dateTime">时间</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>Ticks时间戳</returns>
        public static long GetTicksTimestamp(DateTime dateTime, TimestampUnit timestampUnit = TimestampUnit.Millisecond, uint precision = 1)
        {
            double timestamp = GetTicksTimestampD(dateTime, timestampUnit, precision);
            return Convert.ToInt64(timestamp);
        }

        /// <summary>
        /// 获取指定时间的Ticks时间戳
        /// </summary>
        /// <param name="dateTime">时间</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>Ticks时间戳</returns>
        public static double GetTicksTimestampD(DateTimeOffset dateTime, TimestampUnit timestampUnit = TimestampUnit.Millisecond, uint precision = 1)
        {
            DateTime time = ConvertDateTimeOffsetToDateTime(dateTime, _timestampFactory.RefTime.Kind);
            return GetTicksTimestampD(time, timestampUnit, precision);
        }

        /// <summary>
        /// 获取指定时间的Ticks时间戳
        /// </summary>
        /// <param name="dateTime">时间</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>Ticks时间戳</returns>
        public static long GetTicksTimestamp(DateTimeOffset dateTime, TimestampUnit timestampUnit = TimestampUnit.Millisecond, uint precision = 1)
        {
            double timestamp = GetTicksTimestampD(dateTime, timestampUnit, precision);
            return Convert.ToInt64(timestamp);
        }



        /// <summary>
        /// 获取当前时间的Ticks时间戳
        /// </summary>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>Ticks时间戳</returns>
        public static double GetTicksTimestampD(TimestampUnit timestampUnit = TimestampUnit.Millisecond, uint precision = 1)
        {
            return _timestampFactory.GetTicksTimestampD(timestampUnit, precision);
        }

        /// <summary>
        /// 获取当前时间的Ticks时间戳
        /// </summary>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>Ticks时间戳</returns>
        public static long GetTicksTimestamp(TimestampUnit timestampUnit = TimestampUnit.Millisecond, uint precision = 1)
        {
            return Convert.ToInt64(GetTicksTimestampD(timestampUnit, precision));
        }






        /// <summary>
        /// Ticks时间戳转换为DateTime
        /// </summary>
        /// <param name="timestamp">Ticks时间戳</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="dateTimeKind">时间类型,默认类型为本地时间</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>DateTime</returns>
        public static DateTime TicksTimestampToDateTime(double timestamp, TimestampUnit timestampUnit = TimestampUnit.Millisecond,
            DateTimeKind dateTimeKind = _DEFAULT, uint precision = 1)
        {
            return _timestampFactory.TicksTimestampToDateTime(timestamp, timestampUnit, dateTimeKind, precision);
        }

        /// <summary>
        /// Ticks时间戳转换为DateTimeOffset
        /// </summary>
        /// <param name="timestamp">Ticks时间戳</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="dateTimeKind">时间类型,默认类型为本地时间</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>DateTimeOffset</returns>
        public static DateTimeOffset TicksTimestampToDateTimeOffset(double timestamp, TimestampUnit timestampUnit = TimestampUnit.Millisecond,
             DateTimeKind dateTimeKind = _DEFAULT, uint precision = 1)
        {
            DateTime dateTime = TicksTimestampToDateTime(timestamp, timestampUnit, dateTimeKind, precision);
            return new DateTimeOffset(dateTime);
        }
        #endregion





       

        private const DateTimeKind _DEFAULT = DateTimeKind.Local;
        private static readonly TimestampFactory _localTimestampFactory;
        private static readonly TimestampFactory _utcTimestampFactory;
        private static readonly TimestampFactory _unspecifiedTimestampFactory;


        static TimeEx()
        {
            _localTimestampFactory = new TimestampFactory(DateTimeKind.Local);
            _utcTimestampFactory = new TimestampFactory(DateTimeKind.Utc);
            _unspecifiedTimestampFactory = new TimestampFactory(DateTimeKind.Unspecified);
        }


        #region common

        /// <summary>
        /// 转换DateTimeOffset为DateTime
        /// </summary>
        /// <param name="dateTime">DateTimeOffset</param>
        /// <param name="kind">目标时间类型</param>
        /// <returns>DateTime</returns>
        public static DateTime ConvertDateTimeOffsetToDateTime(DateTimeOffset dateTime, DateTimeKind kind)
        {
            DateTime time;
            switch (kind)
            {
                case DateTimeKind.Local:
                    time = dateTime.LocalDateTime;
                    break;
                case DateTimeKind.Utc:
                    time = dateTime.UtcDateTime;
                    break;
                case DateTimeKind.Unspecified:
                    time = dateTime.DateTime;
                    break;
                default:
                    throw new NotSupportedException(kind.ToString());
            }

            return time;
        }

        /// <summary>
        /// 将已知时间转换为另一种表示的时间
        /// </summary>
        /// <param name="time">已知时间</param>
        /// <param name="targetKind">目标时间类型</param>
        /// <returns>目标时间</returns>
        public static DateTime ConvertDateTimeKind(DateTime time, DateTimeKind targetKind)
        {
            if (time.Kind == targetKind)
            {
                return time;
            }

            switch (targetKind)
            {
                case DateTimeKind.Local:
                    time = time.ToLocalTime();
                    break;
                case DateTimeKind.Utc:
                    time = time.ToUniversalTime();
                    break;
                case DateTimeKind.Unspecified:
                    time = new DateTime(time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second, time.Millisecond, DateTimeKind.Unspecified);
                    break;
                default:
                    throw new NotSupportedException(targetKind.ToString());
            }

            return time;
        }

        /// <summary>
        /// 获取永久时间片
        /// </summary>
        /// <returns>永久时间片</returns>
        public static TimeSpan GetForeverTimeSpan()
        {
            //将1000年当作为永久时间
            return new TimeSpan(365 * 1000, 0, 0, 0, 0);
        }

        #endregion



        #region 基准时间1970-1-1 0:0:0.000时间戳

        private static TimestampFactory GetTimestampFactory(DateTimeKind kind)
        {
            TimestampFactory factory;
            switch (kind)
            {
                case DateTimeKind.Local:
                    factory = _localTimestampFactory;
                    break;
                case DateTimeKind.Utc:
                    factory = _utcTimestampFactory;
                    break;
                case DateTimeKind.Unspecified:
                    factory = _unspecifiedTimestampFactory;
                    break;
                default:
                    throw new NotSupportedException(kind.ToString());
            }

            return factory;
        }



        /// <summary>
        /// 获取指定日期时间的时间戳
        /// </summary>
        /// <param name="dateTime">计算时间戳时间</param>
        /// <param name="kind">时间戳类型,默认类型为本地时间</param>
        /// <returns>当前时间的时间戳</returns>
        public static double GetTimestampD(DateTime dateTime, DateTimeKind kind = _DEFAULT)
        {
            return GetTimestampFactory(kind).GetTimestamp(dateTime);
        }

        /// <summary>
        /// 获取指定日期时间的时间戳
        /// </summary>
        /// <param name="dateTime">计算时间戳时间</param>
        /// <param name="kind">时间戳类型,默认类型为本地时间</param>
        /// <returns>当前时间的时间戳</returns>
        public static long GetTimestamp(DateTime dateTime, DateTimeKind kind = _DEFAULT)
        {
            return Convert.ToInt64(GetTimestampD(dateTime, kind));
        }




        /// <summary>
        /// 获取指定日期时间的时间戳
        /// </summary>
        /// <param name="dateTime">计算时间戳时间</param>
        /// <param name="kind">时间戳类型,默认类型为本地时间</param>
        /// <returns>当前时间的时间戳</returns>
        public static double GetTimestampD(DateTimeOffset dateTime, DateTimeKind kind = _DEFAULT)
        {
            DateTime time = ConvertDateTimeOffsetToDateTime(dateTime, kind);
            return GetTimestampFactory(kind).GetTimestamp(time);
        }

        /// <summary>
        /// 获取指定日期时间的时间戳
        /// </summary>
        /// <param name="dateTime">计算时间戳时间</param>
        /// <param name="kind">时间戳类型,默认类型为本地时间</param>
        /// <returns>当前时间的时间戳</returns>
        public static long GetTimestamp(DateTimeOffset dateTime, DateTimeKind kind = _DEFAULT)
        {
            return Convert.ToInt64(GetTimestampD(dateTime, kind));
        }




        /// <summary>
        /// 获取当前时间的时间戳
        /// </summary>
        /// <param name="kind">时间戳类型,默认类型为本地时间</param>
        /// <returns>当前时间的时间戳</returns>
        public static double GetTimestampD(DateTimeKind kind = _DEFAULT)
        {
            TimestampFactory factory = GetTimestampFactory(kind);
            return factory.GetTimestamp();
        }

        /// <summary>
        /// 获取当前时间的时间戳
        /// </summary>
        /// <param name="kind">时间戳类型,默认类型为本地时间</param>
        /// <returns>当前时间的时间戳</returns>
        public static long GetTimestamp(DateTimeKind kind = _DEFAULT)
        {
            return Convert.ToInt64(GetTimestampD(kind));
        }




        /// <summary>
        /// 时间戳转换为DateTime
        /// </summary>
        /// <param name="timestamp">时间戳</param>
        /// <param name="timestampKind">时间戳对应的时间类型,默认类型为本地时间</param>
        /// <param name="dateTimeKind">时间类型,默认类型为本地时间</param>
        /// <returns>时间</returns>
        public static DateTime TimestampToDateTime(double timestamp, DateTimeKind timestampKind = _DEFAULT, DateTimeKind dateTimeKind = _DEFAULT)
        {
            TimestampFactory timestampFactory = GetTimestampFactory(timestampKind);
            DateTime dateTime = timestampFactory.TimestampToDateTime(timestamp);

            if (dateTime.Kind != dateTimeKind)
            {
                dateTime = TimeEx.ConvertDateTimeKind(dateTime, dateTimeKind);
            }

            return dateTime;
        }

        /// <summary>
        /// 时间戳转换为DateTimeOffset
        /// </summary>
        /// <param name="timestamp">时间戳</param>
        /// <param name="timestampKind">时间戳对应的时间类型,默认类型为本地时间</param>
        /// <param name="dateTimeKind">时间类型,默认类型为本地时间</param>
        /// <returns>时间</returns>
        public static DateTimeOffset TimestampToDateTimeOffset(double timestamp, DateTimeKind timestampKind = _DEFAULT, DateTimeKind dateTimeKind = _DEFAULT)
        {
            DateTime dateTime = TimestampToDateTime(timestamp, timestampKind, dateTimeKind);
            return new DateTimeOffset(dateTime);
        }

        #endregion



        #region TicksTimestamp

        /// <summary>
        /// 获取指定时间的Ticks时间戳
        /// </summary>
        /// <param name="dateTime">时间</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>Ticks时间戳</returns>
        public static double GetTicksTimestampD(DateTime dateTime, TimestampUnit timestampUnit = TimestampUnit.Millisecond, uint precision = 1)
        {
            return GetTimestampFactory(dateTime.Kind).GetTicksTimestampD(dateTime, timestampUnit, precision);
        }

        /// <summary>
        /// 获取指定时间的Ticks时间戳
        /// </summary>
        /// <param name="dateTime">时间</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>Ticks时间戳</returns>
        public static long GetTicksTimestamp(DateTime dateTime, TimestampUnit timestampUnit = TimestampUnit.Millisecond, uint precision = 1)
        {
            double timestamp = GetTicksTimestampD(dateTime, timestampUnit, precision);
            return Convert.ToInt64(timestamp);
        }

        /// <summary>
        /// 获取指定时间的Ticks时间戳
        /// </summary>
        /// <param name="dateTime">时间</param>
        /// <param name="kind">时间戳类型,默认类型为本地时间</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>Ticks时间戳</returns>
        public static double GetTicksTimestampD(DateTimeOffset dateTime, DateTimeKind kind = _DEFAULT, TimestampUnit timestampUnit = TimestampUnit.Millisecond, uint precision = 1)
        {
            DateTime time = ConvertDateTimeOffsetToDateTime(dateTime, kind);
            return GetTicksTimestampD(time, timestampUnit, precision);
        }

        /// <summary>
        /// 获取指定时间的Ticks时间戳
        /// </summary>
        /// <param name="dateTime">时间</param>
        /// <param name="kind">时间戳类型,默认类型为本地时间</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>Ticks时间戳</returns>
        public static long GetTicksTimestamp(DateTimeOffset dateTime, DateTimeKind kind = _DEFAULT, TimestampUnit timestampUnit = TimestampUnit.Millisecond, uint precision = 1)
        {
            double timestamp = GetTicksTimestampD(dateTime, kind, timestampUnit, precision);
            return Convert.ToInt64(timestamp);
        }



        /// <summary>
        /// 获取当前时间的Ticks时间戳
        /// </summary>
        /// <param name="kind">时间戳类型,默认类型为本地时间</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>Ticks时间戳</returns>
        public static double GetTicksTimestampD(DateTimeKind kind = _DEFAULT, TimestampUnit timestampUnit = TimestampUnit.Millisecond, uint precision = 1)
        {
            return GetTimestampFactory(kind).GetTicksTimestampD(timestampUnit, precision);
        }

        /// <summary>
        /// 获取当前时间的Ticks时间戳
        /// </summary>
        /// <param name="kind">时间戳类型,默认类型为本地时间</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>Ticks时间戳</returns>
        public static long GetTicksTimestamp(DateTimeKind kind = _DEFAULT, TimestampUnit timestampUnit = TimestampUnit.Millisecond, uint precision = 1)
        {
            return Convert.ToInt64(GetTicksTimestampD(kind, timestampUnit, precision));
        }






        /// <summary>
        /// Ticks时间戳转换为DateTime
        /// </summary>
        /// <param name="timestamp">Ticks时间戳</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="timestampKind">Ticks时间戳对应的时间类型,默认类型为本地时间</param>
        /// <param name="dateTimeKind">时间类型,默认类型为本地时间</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>DateTime</returns>
        public static DateTime TicksTimestampToDateTime(double timestamp, TimestampUnit timestampUnit = TimestampUnit.Millisecond,
            DateTimeKind timestampKind = _DEFAULT, DateTimeKind dateTimeKind = _DEFAULT, uint precision = 1)
        {
            return GetTimestampFactory(timestampKind).TicksTimestampToDateTime(timestamp, timestampUnit, dateTimeKind, precision);
        }

        /// <summary>
        /// Ticks时间戳转换为DateTimeOffset
        /// </summary>
        /// <param name="timestamp">Ticks时间戳</param>
        /// <param name="timestampUnit">Ticks时间戳单位</param>
        /// <param name="timestampKind">Ticks时间戳对应的时间类型,默认类型为本地时间</param>
        /// <param name="dateTimeKind">时间类型,默认类型为本地时间</param>
        /// <param name="precision">时间戳精度</param>
        /// <returns>DateTimeOffset</returns>
        public static DateTimeOffset TicksTimestampToDateTimeOffset(double timestamp, TimestampUnit timestampUnit = TimestampUnit.Millisecond,
            DateTimeKind timestampKind = _DEFAULT, DateTimeKind dateTimeKind = _DEFAULT, uint precision = 1)
        {
            DateTime dateTime = TicksTimestampToDateTime(timestamp, timestampUnit, timestampKind, dateTimeKind, precision);
            return new DateTimeOffset(dateTime);
        }

        #endregion

        **********************************************************************************************************************************************/








        //备份二
        /**********************************************************************************************************************************************
       private const DateTimeKind _DEFAULT = DateTimeKind.Local;

       private class RefTime
       {
           private readonly DateTimeKind _kind;
           private readonly DateTime _refTime;
           private readonly DateTime _refTimeMax;
           private readonly double _minTimestamp;
           private readonly double _maxTimestamp;

           internal RefTime(DateTimeKind kind)
           {
               this._kind = kind;
               this._refTime = new DateTime(1970, 1, 1, 0, 0, 0, kind);
               this._refTimeMax = new DateTime(9999, 12, 31, 23, 59, 59, kind);
               this._minTimestamp = this.PrimitiveGetTimestamp(kind, this._refTime);
               this._maxTimestamp = this.PrimitiveGetTimestamp(kind, this._refTimeMax);
           }

           internal static DateTime ConvertToUnspecifiedTime(DateTime time)
           {
               return new DateTime(time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second, time.Millisecond, DateTimeKind.Unspecified);
           }

           /// <summary>
           /// 获取指定日期时间的时间戳
           /// </summary>
           /// <param name="kind">时间戳类型</param>
           /// <param name="dateTime">计算时间戳时间</param>
           /// <returns>当前时间的时间戳</returns>
           private double PrimitiveGetTimestamp(DateTimeKind kind, DateTime dateTime)
           {
               if (dateTime.Kind != kind)
               {
                   switch (kind)
                   {
                       case DateTimeKind.Local:
                           dateTime = dateTime.ToLocalTime();
                           break;
                       case DateTimeKind.Utc:
                           dateTime = dateTime.ToUniversalTime();
                           break;
                       case DateTimeKind.Unspecified:
                           dateTime = ConvertToUnspecifiedTime(dateTime);
                           break;
                       default:
                           throw new NotSupportedException(kind.ToString());
                   }
               }

               TimeSpan ts = dateTime - this._refTime;
               return ts.TotalMilliseconds;
           }

           /// <summary>
           /// 获取指定日期时间的时间戳
           /// </summary>
           /// <param name="dateTime">计算时间戳时间</param>
           /// <returns>当前时间的时间戳</returns>
           internal double GetTimestamp(DateTime dateTime)
           {
               return this.PrimitiveGetTimestamp(this._kind, dateTime);
           }

           /// <summary>
           /// 时间戳转换为DateTime
           /// </summary>
           /// <param name="timestamp">时间戳</param>
           /// <returns>时间</returns>
           internal DateTime TimestampToDateTime(double timestamp)
           {
               DateTime time;
               if (timestamp <= this._minTimestamp)
               {
                   time = this._refTime;
               }
               else if (timestamp >= this._maxTimestamp)
               {
                   time = this._refTimeMax;
               }
               else
               {
                   time = this._refTime.AddMilliseconds(timestamp);
               }

               return time;
           }
       }


       private static RefTime _localRefTime;
       private static RefTime _utcRefTime;
       private static RefTime _unspecifiedRefTime;

       static TimeEx()
       {
           _localRefTime = new RefTime(DateTimeKind.Local);
           _utcRefTime = new RefTime(DateTimeKind.Utc);
           _unspecifiedRefTime = new RefTime(DateTimeKind.Unspecified);
       }



       private static RefTime GetRefTime(DateTimeKind kind)
       {
           RefTime refTime;
           switch (kind)
           {
               case DateTimeKind.Local:
                   refTime = _localRefTime;
                   break;
               case DateTimeKind.Utc:
                   refTime = _utcRefTime;
                   break;
               case DateTimeKind.Unspecified:
                   refTime = _unspecifiedRefTime;
                   break;
               default:
                   throw new NotSupportedException(kind.ToString());
           }

           return refTime;
       }

       /// <summary>
       /// 获取指定日期时间的时间戳
       /// </summary>
       /// <param name="dateTime">计算时间戳时间</param>
       /// <param name="kind">时间戳类型,默认类型为本地时间</param>
       /// <returns>当前时间的时间戳</returns>
       public static double GetTimestampD(DateTime dateTime, DateTimeKind kind = _DEFAULT)
       {
           return GetRefTime(kind).GetTimestamp(dateTime);
       }

       /// <summary>
       /// 获取指定日期时间的时间戳
       /// </summary>
       /// <param name="dateTime">计算时间戳时间</param>
       /// <param name="kind">时间戳类型,默认类型为本地时间</param>
       /// <returns>当前时间的时间戳</returns>
       public static long GetTimestamp(DateTime dateTime, DateTimeKind kind = _DEFAULT)
       {
           return Convert.ToInt64(GetTimestampD(dateTime, kind));
       }





       /// <summary>
       /// 获取指定日期时间的时间戳
       /// </summary>
       /// <param name="dateTime">计算时间戳时间</param>
       /// <param name="kind">时间戳类型,默认类型为本地时间</param>
       /// <returns>当前时间的时间戳</returns>
       public static double GetTimestampD(DateTimeOffset dateTime, DateTimeKind kind = _DEFAULT)
       {
           DateTime time;
           switch (kind)
           {
               case DateTimeKind.Local:
                   time = dateTime.LocalDateTime;
                   break;
               case DateTimeKind.Utc:
                   time = dateTime.UtcDateTime;
                   break;
               case DateTimeKind.Unspecified:
                   time = dateTime.DateTime;
                   break;
               default:
                   throw new NotSupportedException(kind.ToString());
           }

           return GetRefTime(kind).GetTimestamp(time);
       }

       /// <summary>
       /// 获取指定日期时间的时间戳
       /// </summary>
       /// <param name="dateTime">计算时间戳时间</param>
       /// <param name="kind">时间戳类型,默认类型为本地时间</param>
       /// <returns>当前时间的时间戳</returns>
       public static long GetTimestamp(DateTimeOffset dateTime, DateTimeKind kind = _DEFAULT)
       {
           return Convert.ToInt64(GetTimestampD(dateTime, kind));
       }





       /// <summary>
       /// 获取当前时间的时间戳
       /// </summary>
       /// <param name="kind">时间戳类型,默认类型为本地时间</param>
       /// <returns>当前时间的时间戳</returns>
       public static double GetTimestampD(DateTimeKind kind = _DEFAULT)
       {
           RefTime refTime;
           DateTime dateTime;
           switch (kind)
           {
               case DateTimeKind.Local:
                   dateTime = DateTime.Now;
                   refTime = _localRefTime;
                   break;
               case DateTimeKind.Utc:
                   dateTime = DateTime.UtcNow;
                   refTime = _utcRefTime;
                   break;
               case DateTimeKind.Unspecified:
                   dateTime = RefTime.ConvertToUnspecifiedTime(DateTime.Now);
                   refTime = _unspecifiedRefTime;
                   break;
               default:
                   throw new NotSupportedException(kind.ToString());
           }

           return refTime.GetTimestamp(dateTime);
       }

       /// <summary>
       /// 获取当前时间的时间戳
       /// </summary>
       /// <param name="kind">时间戳类型,默认类型为本地时间</param>
       /// <returns>当前时间的时间戳</returns>
       public static long GetTimestamp(DateTimeKind kind = _DEFAULT)
       {
           return Convert.ToInt64(GetTimestampD(kind));
       }




       /// <summary>
       /// 时间戳转换为DateTime
       /// </summary>
       /// <param name="timestamp">时间戳</param>
       /// <param name="timestampKind">时间戳类型,默认类型为本地时间</param>
       /// <param name="dateTimeKind">时间类型,默认类型为本地时间</param>
       /// <returns>时间</returns>
       public static DateTime TimestampToDateTime(double timestamp, DateTimeKind timestampKind = _DEFAULT, DateTimeKind dateTimeKind = _DEFAULT)
       {
           RefTime refTime = GetRefTime(timestampKind);
           DateTime dateTime = refTime.TimestampToDateTime(timestamp);

           if (dateTime.Kind != dateTimeKind)
           {
               switch (dateTimeKind)
               {
                   case DateTimeKind.Local:
                       dateTime = dateTime.ToLocalTime();
                       break;
                   case DateTimeKind.Utc:
                       dateTime = dateTime.ToUniversalTime();
                       break;
                   case DateTimeKind.Unspecified:
                       dateTime = RefTime.ConvertToUnspecifiedTime(dateTime);
                       break;
                   default:
                       throw new NotSupportedException(dateTimeKind.ToString());
               }
           }

           return dateTime;
       }

       /// <summary>
       /// 时间戳转换为DateTimeOffset
       /// </summary>
       /// <param name="timestamp">时间戳</param>
       /// <param name="timestampKind">时间戳类型,默认类型为本地时间</param>
       /// <param name="dateTimeKind">时间类型,默认类型为本地时间</param>
       /// <returns>时间</returns>
       public static DateTimeOffset TimestampToDateTimeOffset(double timestamp, DateTimeKind timestampKind = _DEFAULT, DateTimeKind dateTimeKind = _DEFAULT)
       {
           DateTime dateTime = TimestampToDateTime(timestamp, timestampKind, dateTimeKind);
           return new DateTimeOffset(dateTime);
       }
       **********************************************************************************************************************************************/


    }
}
